package com.mustang.core.client;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Node;
import com.mustang.core.client.type.JsObject;
import com.mustang.core.client.type.JsArray;
import com.mustang.core.client.type.Func;

/**
 * This is the lightweight jQuery representative class in the GWT,It wraps all
 * the jQuery API ,to facilitate the development of using jQuery by GWT
 * development. 
 * 
 * Progress:
 * jQuery Core done
 * Selectors done
 * Attributes done
 * Traversing done
 * Manipulation 
 * CSS done
 * Events 
 * Effects 
 * Ajax 
 * Utilities 
 * jQuery UI
 * 
 * @author Jason.Cui
 */

public final class GQuery extends JavaScriptObject
{
	
	
	protected GQuery(){}
	

	//Core API
	/**
	 * Returning an Empty Set
	 * 
	 * @param gQuery
	 * @return
	 */
	public native static GQuery $()/*-{
		return $wnd.$();
	}-*/;

	/**
	 * Return the gQuery by the given selector
	 * 
	 * @param selector
	 *          A string containing a selector expression
	 */
	public native static GQuery $(String selector)/*-{
		return $wnd.$(selector);
	}-*/;

	/**
	 * A DOM element to wrap in a gQuery object.
	 * 
	 * @param elem
	 * @return
	 */
	public native static GQuery $(Node context)/*-{
		return $wnd.$(context);
	}-*/;
	
	/**
	 * A JsObject to wrap in a gQuery object.
	 * 
	 * @param elem
	 * @return
	 */
	public native static GQuery $(JsObject obj)/*-{
		return $wnd.$(obj);
	}-*/;

	/**
	 * A Array of DOM elements to wrap in a gQuery object.
	 * 
	 * @param elem
	 * @return
	 */
	public native static GQuery $(JsArray<Node> array)/*-{
		return $wnd.$(array);
	}-*/;

	/**
	 * An existing gQuery object to clone.
	 * 
	 * @param gQuery
	 * @return
	 */
	public native static GQuery $(GQuery gQuery)/*-{
		return $wnd.$(gQuery);
	}-*/;

	/**
	 * 
	 * @param selector
	 *          A string containing a selector expression or A string of HTML to
	 *          create on the fly. Note that this parses HTML, not XML
	 * @param context
	 *          A DOM Element, Document, or gQuery to use as context
	 * @return
	 */
	public native static GQuery $(String selector, Node context)/*-{
		return $wnd.$(selector,context);
	}-*/;

	/**
	 * Create gQuery by given parameters
	 * 
	 * @param selector
	 *          A string containing a selector expression or A string of HTML to
	 *          create on the fly. Note that this parses HTML, not XML.
	 * @param att
	 *          An map of attributes, events, and methods to call on the
	 *          newly-created element
	 * @return
	 */
	public native static GQuery $(String selector, JsObject attr)/*-{
		return $wnd.$(selector,attr);
	}-*/;

	/**
	 * Create gQuery by given parameters
	 * 
	 * @param selector
	 *          A string containing a selector expression or A string of HTML to
	 *          create on the fly. Note that this parses HTML, not XML.
	 * @param context
	 *          A gQuery to use as context.
	 * @return
	 */
	public native static GQuery $(String selector, GQuery context)/*-{
		return $wnd.$(selector,context);
	}-*/;

	/**
	 * Equal to $(document).ready(function (){...});It triggers when the DOM is ready
	 * 
	 * @param callback The function to execute when the DOM is ready.
	 * 
	 * @return
	 */
	public native static GQuery $(Func callback)/*-{
		//Assign the dynamic functionHolder
		return $wnd.jQuery(function($){
						// Your code using failsafe $ alias here...
						callback.@com.mustang.core.client.type.Func::apply(Lcom/mustang/core/client/GQuery;)(this);
				});
	}-*/;
	
	
	/**
	 * Relinquish jQuery's control of the $ variable
	 * 
	 */
	public static void noConflict()
	{
		noConflict(false);
	}

	/**
	 * Relinquish jQuery's control of the $ variable
	 * 
	 * @param removeAll
	 *          A Boolean indicating whether to remove all jQuery variables from
	 *          the global scope (including jQuery itself).
	 */
	public native static void noConflict(boolean removeAll)/*-{
		$wnd.$.noConflict(removeAll);
	}-*/;
	
	//- Core API End
	
	
	//Attributes (These methods get and set DOM attributes of elements.)
	/**
	 * Adds the specified class(es) to each of the set of matched elements.
	 * 
	 *@param className
	 *          One or more class names to be added to the class attribute of each
	 *          matched element.
	 */
	public native void addClass(String className)/*-{
		this.addClass(className);
	}-*/;

	
	/**
	 * Adds the specified class(es) to each of the set of matched elements.
	 * 
	 * @param function
	 *          (index, class) A function returning one or more space-separated
	 *          class names to be added. Receives the index position of the
	 *          element in the set and the old class value as arguments.
	 * 
	 * 
	 * 
	 */
	public native void addClass(Func func)/*-{
		this.addClass(function(index,cls){
			func.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;I)("index",index);
			func.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;Ljava/lang/String;)("class",cls);
			func.@com.mustang.core.client.type.Func::apply(Lcom/mustang/core/client/GQuery;)(this);
			return func.@com.mustang.core.client.type.Func::returnString()();
		});
	}-*/;
	
	/**
	 * Get the value of an attribute for the first element in the set of matched elements.
	 * 
	 * @param attributeName The name of the attribute to get.
	 * @return
	 */
	public native String attr(String attributeName)/*-{
		return this.attr(attributeName)	
	}-*/;
	
	
	/**
	 * Set one or more attributes for the set of matched elements.
	 * 
	 * @param attributeName The name of the attribute to set
	 * @param value A value to set for the attribute.
	 * @return
	 */
	public native GQuery attr(String attributeName, String value)/*-{
		return this.attr(attributeName,value);
	}-*/;
	
	
	/**
	 * Set one or more attributes for the set of matched elements.
	 * 
	 * @param attributeName The name of the attribute to set
	 * @param value A value to set for the attribute.
	 * @return
	 */
	public native GQuery attr(JsObject map)/*-{
		return this.attr(map);
	}-*/;
	
	
	/**
	 * 
	 * @param attributeName
	 *          The name of the attribute to set
	 * @param function
	 *          (index, attr)A function returning the value to set. this is the
	 *          current element. Receives the index position of the element in the
	 *          set and the old attribute value as arguments.
	 * @return
	 */
	public native GQuery attr(String attributeName, Func func)/*-{
		return this.attr(attributeName,function(index,attr){
				func.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;I)("index",index);
				func.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;Ljava/lang/String;)("attr",attr);
				func.@com.mustang.core.client.type.Func::apply(Lcom/mustang/core/client/GQuery;)(this);
				return func.@com.mustang.core.client.type.Func::returnString()();
		});
	}-*/;
	
	/**
	 * Determine whether any of the matched elements are assigned the given class.
	 * @param cls The class name to search for.
	 *	
	 * @return return true if the given class is found in the element,otherwise return false
	 */
	public native boolean hasClass(String cls)/*-{
		return this.hasClass(cls);
	}-*/;
	
	
	/**
	 * Get the HTML contents of the first element in the set of matched elements.
	 * 
	 * @return 
	 */
	public native String html()/*-{
		return this.html();
	}-*/;
	
	
	/**
	 * Set the HTML contents of each element in the set of matched elements.
	 * 
	 * @param htmlString
	 *          A string of HTML to set as the content of each matched element.
	 * 
	 * @return
	 */
	public native GQuery html(String htmlString)/*-{
		return this.html(htmlString);
	}-*/;
	
	
	
	/**
	 * Set the HTML contents of each element in the set of matched elements.
	 * 
	 * @param func
	 *          function(index, oldhtml)A function returning the HTML content to
	 *          set. Receives the index position of the element in the set and the
	 *          old HTML value as arguments. jQuery empties the element before
	 *          calling the function; use the oldhtml argument to reference the
	 *          previous content.
	 * 
	 * 
	 * @return
	 */
	public native GQuery html(Func func)/*-{
		return this.html(function(index, oldhtml){
				func.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;I)("index",index);
				func.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;Ljava/lang/String;)("oldhtml",oldhtml);
			  func.@com.mustang.core.client.type.Func::apply(Lcom/mustang/core/client/GQuery;)(this);
			  return func.@com.mustang.core.client.type.Func::returnString()();
		});
	}-*/;
	
	
	/**
	 * Remove an attribute from each element in the set of matched elements.
	 * 
	 * @param attributeName
	 *          An attribute to remove.
	 * @return
	 */
	public native GQuery removeAttr(String attributeName)/*-{
		return this.removeAttr(attributeName);
	}-*/;
	
	
	/**
	 * Remove a single class, multiple classes, or all classes from each element
	 * in the set of matched elements
	 * 
	 * @param className
	 *          A class name to be removed from the class attribute of each
	 *          matched element.
	 * @return
	 */
	public native GQuery removeClass(String className)/*-{
		return this.removeClass(className);
	}-*/;
	
	
	/**
	 * Remove all classes from each element in the set of matched elements
	 * 
	 * @return
	 */
	public native GQuery removeClass()/*-{
		return this.removeClass();
	}-*/;
	
	
	/**
	 * Remove a single class, multiple classes, or all classes from each element
	 * in the set of matched elements
	 * 
	 * @param func
	 *          function(index, class)A function returning one or more
	 *          space-separated class names to be removed. Receives the index
	 *          position of the element in the set and the old class value as
	 *          arguments.
	 * 
	 * @return
	 */
	public native GQuery removeClass(Func func)/*-{
		return this.removeClass(function(index, cls){
			func.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;I)("index",index);
			func.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;Ljava/lang/String;)("class",cls);
			func.@com.mustang.core.client.type.Func::apply(Lcom/mustang/core/client/GQuery;)(this);
			return func.@com.mustang.core.client.type.Func::returnString()();
		});
	}-*/;
	
	
	/**
	 * Add or remove one or more classes from each element in the set of matched
	 * elements, depending on either the class's presence or the value of the
	 * switch argument.
	 * 
	 * 
	 * @param className
	 *          One or more class names (separated by spaces) to be toggled for
	 *          each element in the matched set.
	 * 
	 * @return
	 */
	public native GQuery toggleClass(String className)/*-{
		return this.toggleClass(className);
	}-*/;
	
	/**
	 * Add or remove one or more classes from each element in the set of matched
	 * elements, depending on either the class's presence or the value of the
	 * switch argument.
	 * 
	 * @param className
	 *          One or more class names (separated by spaces) to be toggled for
	 *          each element in the matched set.
	 * 
	 * @param needSwitch
	 *          A boolean value to determine whether the class should be added or
	 *          removed.
	 * @return
	 */
	public native GQuery toggleClass(String className, boolean needSwitch)/*-{
		return this.toggleClass(className,needSwitch);
	}-*/;
	
	
	/**
	 * Add or remove one or more classes from each element in the set of matched
	 * elements, depending on either the class's presence or the value of the
	 * switch argument.
	 * 
	 * @param func
	 *          function(index, class)A function that returns class names to be
	 *          toggled in the class attribute of each element in the matched set.
	 *          Receives the index position of the element in the set and the old
	 *          class value as arguments.
	 * 
	 * 
	 * @param needSwitch
	 * @return A boolean value to determine whether the class should be added or
	 *         removed.
	 */
	public native GQuery toggleClass(Func func, boolean needSwitch)/*-{
		return this.toggleClass(function(index,cls){
		  func.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;I)("index",index);
			func.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;Ljava/lang/String;)("class",cls);
			func.@com.mustang.core.client.type.Func::apply(Lcom/mustang/core/client/GQuery;)(this);
			return func.@com.mustang.core.client.type.Func::returnString()();
		},needSwitch);
	}-*/;

	/**
	 * Add or remove one or more classes from each element in the set of matched
	 * elements, depending on either the class's presence or the value of the
	 * switch argument.
	 * 
	 * @param func
	 *          function(index, class)A function that returns class names to be
	 *          toggled in the class attribute of each element in the matched set.
	 *          Receives the index position of the element in the set and the old
	 *          class value as arguments.
	 * @return
	 */
	public native GQuery toggleClass(Func func)/*-{
		return this.toggleClass(function(index,cls){
		  func.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;I)("index",index);
			func.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;Ljava/lang/String;)("class",cls);
			func.@com.mustang.core.client.type.Func::apply(Lcom/mustang/core/client/GQuery;)(this);
			return func.@com.mustang.core.client.type.Func::returnString()();
		});
	}-*/;
	
	
	/**
	 * Get the current value of the first element in the set of matched elements.
	 * 
	 * 
	 * @return
	 */
	public native String valOfString()/*-{
		return this.val();
	}-*/;
	
	

	/**
	 * Set the value of each element in the set of matched elements.
	 * 
	 * 
	 * @param value
	 *          A string of text to set as the value property of each matched
	 *          element.
	 * 
	 * 
	 * @return
	 */
	public native GQuery val(String value)/*-{
		return this.val( value);
	}-*/;
	
	/**
	 * Set the value of each element in the set of matched elements.
	 * 
	 * 
	 * @param func
	 *          (index, value)A function returning the value to set.
	 * 
	 * 
	 * 
	 * 
	 * @return
	 */
	public native GQuery val(Func func)/*-{
		return this.val( function(index,value){
		  func.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;I)("index",index);
			func.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;Ljava/lang/String;)("value",value);
			func.@com.mustang.core.client.type.Func::apply(Lcom/mustang/core/client/GQuery;)(this);
			return func.@com.mustang.core.client.type.Func::returnString()();
		});
	}-*/;
	
	
	/**
	 * Get the current value of the first element in the set of matched elements.
	 * 
	 * 
	 * @return
	 */
	public native JsArray<?> valOfArray()/*-{
		//make sure the return will not return undefined object ,so use ||[]
		return this.val()||[];
	}-*/;
	
	//-Attributes API End
	
	
	//-CSS(These methods get and set CSS-related properties of elements.)
	
	
	/**
	 * Get the value of a style property for the first element in the set of
	 * matched elements.
	 * 
	 * @param propertyName
	 *          A CSS property.
	 */
	public native String css(String propertyName)/*-{
		return this.css(propertyName);
	}-*/;
	
	
	/**
	 * Set one or more CSS properties for the set of matched elements.
	 * 
	 * 
	 * @param propertyName
	 *          A CSS property name.
	 * 
	 * @param value
	 *          A value to set for the property.
	 * @return GQuery instance
	 */
	public native GQuery css(String propertyName, String value)/*-{
		return this.css(propertyName,value);
	}-*/;
	
	
	/**
	 * Set one or more CSS properties for the set of matched elements.
	 * 
	 * @param propertyName
	 *          A CSS property name.
	 * @param func
	 *          function(index, value)A function returning the value to set.
	 *          Receives the index position of the element in the set and the old
	 *          value as arguments
	 * @return GQuery instance
	 */
	public native GQuery css(String propertyName, Func func)/*-{
		return this.css(propertyName,function(index,value){
		  func.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;I)("index",index);
			func.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;Ljava/lang/String;)("value",value);
			func.@com.mustang.core.client.type.Func::apply(Lcom/mustang/core/client/GQuery;)(this);
			return func.@com.mustang.core.client.type.Func::returnString()();
		});
	}-*/;
	
	
	
	/**
	 * Set one or more CSS properties for the set of matched elements.
	 * 
	 * @param map
	 *          A map of property-value pairs to set.
	 * 
	 * @return GQuery instance
	 */
	public native GQuery css(JsObject map)/*-{
		return this.css(map);
	}-*/;
	
	
	/**
	 * Get the current computed height for the first element in the set of matched
	 * elements.
	 * 
	 * 
	 * @return
	 */
	public native int height()/*-{
		return this.height();
	}-*/;
	
	/**
	 * Set the CSS height of every matched element.
	 * 
	 * @param height
	 *          An integer representing the number of pixels, or an integer with
	 *          an optional unit of measure appended (as a string).
	 * 
	 * 
	 * @return
	 */
	public native GQuery height(int height)/*-{
	return this.height(height);
	}-*/;
	
	/**
	 * Set the CSS height of every matched element.
	 * 
	 * @param height
	 *          An integer representing the number of pixels, or an integer with
	 *          an optional unit of measure appended (as a string).
	 * 
	 * 
	 * @return
	 */
	public native GQuery height(String height)/*-{
	return this.height(height);
	}-*/;
	
	
	/**
	 * Set the CSS height of every matched element.
	 * 
	 * @param func
	 *          function(index, height)A function returning the height to set.
	 *          Receives the index position of the element in the set and the old
	 *          height as arguments.
	 * 
	 * 
	 * @return
	 */
	public native GQuery height(Func func)/*-{
		return this.height(function(index,height){
		 	func.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;I)("index",index);
			func.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;I)("height",height);
			func.@com.mustang.core.client.type.Func::apply(Lcom/mustang/core/client/GQuery;)(this);
			return func.@com.mustang.core.client.type.Func::returnInt()();
		});
	}-*/;
	
	
	/**
	 * Get the current computed height for the first element in the set of matched
	 * elements, including padding but not border.
	 * 
	 * @return
	 */
	public native int innerHeight()/*-{
		return this.innerHeight();
	}-*/;
	
	/**
	 * Get the current computed width for the first element in the set of matched
	 * elements, including padding but not border.
	 * 
	 * @return
	 */
	public native int innerWidth()/*-{
		return this.innerWidth();
	}-*/;

	/**
	 * Get the current coordinates of the first element in the set of matched
	 * elements, relative to the document
	 * 
	 * @return returns an object containing the properties top and left.
	 */
	public native Offset offset()/*-{
		return this.offset();
	}-*/;
	
	/**
	 * Set the current coordinates of every element in the set of matched
	 * elements, relative to the document.
	 * 
	 * @param coordinates
	 *          An object containing the properties top and left, which
	 *          are integers indicating the new top and left coordinates for the
	 *          elements.
	 * @return
	 */
	public native GQuery offset(JsObject coordinates)/*-{
		return this.offset(coordinates);
	}-*/;

	/**
	 *  PLEASE DON'T USE THIS API UNTIL FURTHER UPDATES!!
	 *  
	 * Set the current coordinates of every element in the set of matched
	 * elements, relative to the document.
	 * 
	 * @param func
	 *          function(index, coords)A function to return the coordinates to
	 *          set. Receives the index of the element in the collection as the
	 *          first argument and the current coordinates as the second argument.
	 *          The function should return an object with the new top and left
	 *          properties.
	 * 
	 * @link http://api.jquery.com/offset/
	 * @note post a defect on this API,please see below comments: try to add below
	 *       script $("p:last").offset(function(index,coords){ alert(index);
	 *       alert(coords.left); }); ,IE simply raises Error such as
	 *       "'top' is null or not an object"
	 * 
	 *       Don't know what's wrong.
	 *       
	 *      
	 * 
	 * @return
	 */
	public native GQuery offset(Func func)/*-{
		return this.offset(function(index,coords){
				func.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;I)("index",index);
				func.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;Lcom/mustang/core/client/type/JsObject;)("coords",coords);
				func.@com.mustang.core.client.type.Func::apply(Lcom/mustang/core/client/GQuery;)(this);
				return func.@com.mustang.core.client.type.Func::returnJsObject()();
		});
	}-*/;
	
	
	/**
	 * Get the current computed height for the first element in the set of matched
	 * elements, including padding, border, and margin
	 * 
	 * @return
	 */
	public native int outerHeight(boolean includeMargin )/*-{
			return this.outerHeight(includeMargin);
	}-*/;
	
	/**
	 * Get the current computed height for the first element in the set of matched
	 * elements, including padding, border, exclude the margin
	 * 
	 * @return
	 */
	public int outerHeight()
	{
		return this.outerHeight(false);
	}
	
	/**
	 * Get the current computed width for the first element in the set of matched
	 * elements, including padding and border.
	 * 
	 * @param includeMargin
	 *          A Boolean indicating whether to include the element's margin in
	 *          the calculation.
	 * 
	 * @return
	 */
	public native int outerWidth(boolean includeMargin)/*-{
		return this.outerWidth(includeMargin);
	}-*/;
	
	/**
	 * Get the current computed width for the first element in the set of matched
	 * elements, does not include padding and border.
	 * 
	 * @return
	 */
	public int outerWidth()
	{
		return this.outerWidth(false);
	}
	
	/**
	 * Get the current coordinates of the first element in the set of matched
	 * elements, relative to the offset parent.
	 * 
	 * @return
	 */
	public native Offset position()/*-{
		return this.position();
	}-*/;
	
	/**
	 * Get the current horizontal position of the scroll bar for the first element
	 * in the set of matched elements.
	 * 
	 * @return
	 */
	public native int scrollLeft()/*-{
		return this.scrollLeft();
	}-*/;
	
	/**
	 * Set the current horizontal position of the scroll bar for each of the set
	 * of matched elements
	 * 
	 * @param value
	 *          An integer indicating the new position to set the scroll bar to.
	 * 
	 * 
	 * @return
	 */
	public native GQuery scrollLeft(int value)/*-{
		return this.scrollLeft(value);
	}-*/;
		
	
	/**
	 * Get the current vertical position of the scroll bar for the first element
	 * in the set of matched elements.
	 * 
	 * @return
	 */
	public native int scrollTop()/*-{
		return this.scrollTop();
	}-*/;
	
	/**
	 * Set the current vertical position of the scroll bar for each of the set of
	 * matched elements.
	 * 
	 * @param value
	 * @return
	 */
	public native GQuery scrollTop(int value)/*-{
		return this.scrollTop(value);
	}-*/;
	
	
	/**
	 * Get the current computed width for the first element in the set of matched
	 * elements.
	 * 
	 * @return
	 */
	public native int width()/*-{
		return this.width();
	}-*/;
	
	
	/**
	 * Set the CSS width of each element in the set of matched elements.
	 * 
	 * @param value
	 *          An integer representing the number of pixels, or an integer along
	 *          with an optional unit of measure appended (as a string).
	 * 
	 * @return
	 */
	public native GQuery width(int value)/*-{
		return this.width(value);
	}-*/;
	
	
	/**
	 * Set the CSS width of each element in the set of matched elements.
	 * 
	 * @param value
	 *          An integer representing the number of pixels, or an integer along
	 *          with an optional unit of measure appended (as a string).
	 * 
	 * @return
	 */
	public native GQuery width(String value)/*-{
		return this.width(value);
	}-*/;
	
	
	/**
	 * Set the CSS width of each element in the set of matched elements.
	 * 
	 * @param func
	 *          function(index, width)A function returning the width to set.
	 *          Receives the index position of the element in the set and the old
	 *          width as arguments.
	 * @return
	 */
	public native GQuery width(Func func)/*-{
		return this.width(function(index,width){
			func.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;I)("index",index);
			func.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;I)("width",width);
			func.@com.mustang.core.client.type.Func::apply(Lcom/mustang/core/client/GQuery;)(this);
			return func.@com.mustang.core.client.type.Func::returnInt()();
		});
	}-*/;
	
	//-CSS API End
	
	//Traversing API Start
	
	/**
	 * Add elements to the set of matched elements.
	 * 
	 * 
	 * @param selector
	 *          A string containing a selector expression to match additional
	 *          elements against. Or An HTML fragment to add to the set of matched
	 *          elements.
	 * @Note 
	 */
	public native GQuery add(String selector)/*-{
		return this.add(selector);
	}-*/;
	
	/**
	 * Add elements to the set of matched elements.
	 * 
	 * @param elements one or more elements to add to the set of matched elements.
	 * @return 
	 */
	public native GQuery add(Node elements)/*-{
		return this.add(elements);
	}-*/;
	
	/**
	 * 
	 * @param selector
	 *          A string containing a selector expression to match additional
	 *          elements against
	 * @param context
	 *          Add some elements rooted against the specified context.
	 * @return
	 */
	public native GQuery add(String selector, Node context)/*-{
	return this.add(selector,context);
	}-*/;
	
	
	/**
	 * Add the previous set of elements on the stack to the current set.
	 * 
	 * @return
	 */
	public native GQuery addSelf()/*-{
		return this.addSelf();
	}-*/;
	
	
	/**
	 * Get the children of each element in the set of matched elements
	 * 
	 * @return
	 */
	public native GQuery children()/*-{
		return this.children();
	}-*/;
	
	/**
	 * Get the children of each element in the set of matched elements, filtered
	 * by a selector.
	 * 
	 * @param selector
	 *          A string containing a selector expression to match
	 *          elements against
	 * @return
	 */
	public native GQuery children(String selector)/*-{
		return this.children(selector);
	}-*/;
	
	/**
	 * Get the first ancestor element that matches the selector, beginning at the
	 * current element and progressing up through the DOM tree
	 * 
	 * @return
	 */
	public native GQuery closest()/*-{
			return this.closest();
	}-*/;
	
	
	/**
	 * Get the first ancestor element that matches the selector, beginning at the
	 * current element and progressing up through the DOM tree
	 * 
	 * @param selector
	 *          A string containing a selector expression to match elements
	 *          against.
	 * 
	 * @return
	 */
	public native GQuery closest(String selector)/*-{
		return this.closest(selector);
	}-*/;
	
	
	/**
	 * Get the first ancestor element that matches the selector, beginning at the
	 * current element and progressing up through the DOM tree
	 * @param selector A string containing a selector expression to match elements
	 *          against.
	 * @param context The DOM context where the traversing should limited within
	 * @return
	 */
	public native GQuery closest(String selector, Node context)/*-{
		return this.closest(selector);
	}-*/;
	
	/**
	 * Gets an array of all the elements and selectors matched against the current
	 * element up through the DOM tree
	 * 
	 * @param selectors
	 *          An array or string containing a selector expression to match
	 *          elements against (can also be a jQuery object).
	 * 
	 * @return
	 */
	public native JsArray<GQuery> closest(JsArray<String> selectors)/*-{
		return this.closest(selectors);
	}-*/;

	/**
	 * Gets an array of all the elements and selectors matched against the current
	 * element up through the DOM tree
	 * 
	 * @param selectors
	 *          An array or string containing a selector expression to match
	 *          elements against (can also be a jQuery object).
	 * @param context
	 *          A DOM element within which a matching element may be found. If no
	 *          context is passed in then the context of the jQuery set will be
	 *          used instead.
	 * @return
	 */
	public native JsArray<GQuery> closest(JsArray<String> selectors, Node context)/*-{
		return this.closest(selectors,context);
	}-*/;

	
	/**
	 * Get the children of each element in the set of matched elements, including
	 * text nodes.
	 * 
	 * @return
	 */
	public native GQuery contents()/*-{
		return this.contents();
	}-*/;
	
	/**
	 * Iterate over a jQuery object, executing a function for each matched
	 * element.
	 * 
	 * @param func
	 *          function(index, Element)A function to execute for each matched
	 *          element.
	 */
	public native void each(Func func)/*-{
		this.each(function(index,element){
			func.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;I)("index",index);
			func.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;Lcom/mustang/core/client/type/JsObject;)("element",element);
			func.@com.mustang.core.client.type.Func::apply(Lcom/mustang/core/client/GQuery;)(this);
		});
	}-*/;
	
	/**
	 * End the most recent filtering operation in the current chain and return the
	 * set of matched elements to its previous state.
	 * 
	 * @return
	 */
	public native GQuery end()/*-{
		return this.end();
	}-*/;
	
	/**
	 * Reduce the set of matched elements to the one at the specified index.
	 * 
	 * @param index
	 *          An positive integer indicating the 0-based position of the
	 *          element. 
	 *          An negative integer indicating the position of the
	 *          element, counting backwards from the last element in the set.
	 * 
	 * 
	 * @return
	 */
	public native GQuery eq(int index)/*-{
		return this.eq(index);
	}-*/;

	/**
	 * Reduce the set of matched elements to those that match the selector or pass
	 * the function's test.
	 * 
	 * @param selector
	 *          A string containing a selector expression to match elements
	 *          against.
	 * 
	 * @return
	 */
	public native GQuery filter(String selector)/*-{
		return this.filter(selector);
	}-*/;
	
	
	
	/**
	 * Reduce the set of matched elements to those that match the selector or pass
	 * the function's test.
	 * 
	 * @param selector
	 *          A string containing a selector expression to match elements
	 *          against.
	 * 
	 * @return
	 */
	public native GQuery filter(Func func)/*-{
		return this.filter(function(index){
				func.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;I)("index",index);
				func.@com.mustang.core.client.type.Func::apply(Lcom/mustang/core/client/GQuery;)(this);
				return func.@com.mustang.core.client.type.Func::returnBoolean()();
		});
	}-*/;
	
	
	/**
	 * Get the descendants of each element in the current set of matched elements,
	 * filtered by a selector.
	 * 
	 * @return
	 */
	public native GQuery find(String selector)/*-{
		return this.find(selector);
	}-*/;

	
	/**
	 * Reduce the set of matched elements to the first in the set.
	 * 
	 * @return
	 */
	public native GQuery first()/*-{
		return this.first();
	}-*/;
	
	/**
	 * Reduce the set of matched elements to those that have a descendant that
	 * matches the selector or DOM element.
	 * 
	 * @param selector
	 *          A string containing a selector expression to match elements
	 *          against.
	 * 
	 * @return
	 */
	public native GQuery has(String selector)/*-{
		return this.has(selector);
	}-*/;

	
	/**
	 * Reduce the set of matched elements to those that have a descendant that
	 * matches the selector or DOM element
	 * 
	 * @param contained
	 *          A DOM element to match elements against.
	 * @return
	 */
	public native GQuery has(Node contained)/*-{
		return this.has(contained);
	}-*/;
	
	/**
	 * Check the current matched set of elements against a selector and return
	 * true if at least one of these elements matches the selector.
	 * 
	 * @param selector
	 *          A string containing a selector expression to match elements
	 *          against.
	 * 
	 * @return
	 */
	public native boolean is(String selector)/*-{
		return this.is(selector);
	}-*/;
	
	/**
	 * Reduce the set of matched elements to the final one in the set.

	 * @return
	 */
	public native GQuery last()/*-{
		return this.last();
	}-*/;
	
	/**
	 * Pass each element in the current matched set through a function, producing
	 * a new jQuery object containing the return values
	 * 
	 * @param func
	 *          callback(index, domElement)A function object that will be invoked
	 *          for each element in the current set.
	 * 
	 * 
	 * @return
	 */
	public native GQuery map(Func callback)/*-{
		return this.map(function(index,domElement){
				callback.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;I)("index",index);
				callback.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;Lcom/mustang/core/client/type/JsObject;)("domElement",domElement);
				callback.@com.mustang.core.client.type.Func::apply(Lcom/mustang/core/client/GQuery;)(this);
				return callback.@com.mustang.core.client.type.Func::returnString()();
		});
	}-*/;
	
	/**
	 * Get the immediately following sibling of each element in the set of matched
	 * elements, optionally filtered by a selector
	 * 
	 * @return
	 */
	public native GQuery next()/*-{
		return this.next();
	}-*/;
	
	/**
	 * Get the immediately following sibling of each element in the set of matched
	 * elements, optionally filtered by a selector
	 * 
	 * @param selector
	 * @return
	 */
	public native GQuery next(String selector)/*-{
		return this.next(selector);
	}-*/;
	
	/**
	 * Get all following siblings of each element in the set of matched elements,
	 * optionally filtered by a selector.
	 * 
	 * @return
	 */
	public native GQuery nextAll()/*-{
		return this.nextAll();
	}-*/;

	/**
	 * Get all following siblings of each element in the set of matched elements,
	 * optionally filtered by a selector.
	 * 
	 * @param selector
	 *          A string containing a selector expression to match elements
	 *          against.
	 * 
	 * @return
	 */
	public native GQuery nextAll(String selector)/*-{
		return this.nextAll(selector);
	}-*/;
	
	/**
	 * Get all following siblings of each element up to but not including the
	 * element matched by the selector.
	 * 
	 * @return
	 */
	public native GQuery nextUntil()/*-{
		return this.nextUntil();
	}-*/;

	/**
	 * Get all following siblings of each element up to but not including the
	 * element matched by the selector.
	 * 
	 * @param selector
	 *          A string containing a selector expression to indicate where to
	 *          stop matching following sibling elements.
	 * 
	 * @return
	 */
	public native GQuery nextUntil(String selector)/*-{
		return this.nextUntil(selector);
	}-*/;
	
	
	/**
	 * Remove elements from the set of matched elements.
	 * 
	 * @param selector
	 *          A string containing a selector expression to match elements
	 *          against.
	 * 
	 * @return
	 */
	public native GQuery not(String selector)/*-{
		return this.not(selector);
	}-*/;

	/**
	 * Remove elements from the set of matched elements.
	 * 
	 * @param elements
	 *          One or more DOM elements to remove from the matched set.
	 * @return
	 */
	public native GQuery not(JsArray<?> elements)/*-{
		return this.not(elements);
	}-*/;

	
	/**
	 * Remove elements from the set of matched elements.
	 * 
	 * @param node
	 *          One DOM elements to remove from the matched set.
	 * @return
	 */
	public native GQuery not(Node node)/*-{
		return this.not(node);
	}-*/;
	
	/**
	 * Remove elements from the set of matched elements.
	 * 
	 * @param func
	 *          function(index)A function used as a test for each element in the
	 *          set. this is the current DOM element.
	 * 
	 * 
	 * @return
	 */
	public native GQuery not(Func func)/*-{
		return this.not(function(index){
			func.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;I)("index",index);
			func.@com.mustang.core.client.type.Func::apply(Lcom/mustang/core/client/GQuery;)(this);
			return func.@com.mustang.core.client.type.Func::returnBoolean()(); 
		});
	}-*/;
	
	/**
	 * Get the closest ancestor element that is positioned.
	 * Note,only apply the parent who has the CSS position set as 'relative','absolute','fixed'
	 * @return
	 */
	public native GQuery offsetParent()/*-{
		return this.offsetParent();
	}-*/;
	
	
	/**
	 * Get the parent of each element in the current set of matched elements,
	 * optionally filtered by a selector. It only travels a single level up the
	 * DOM tree
	 * 
	 * @return
	 */
	public native GQuery parent()/*-{
		return this.parent();
	}-*/;

	/**
	 * Get the parent of each element in the current set of matched elements,
	 * optionally filtered by a selector. It only travels a single level up the
	 * DOM tree
	 * 
	 * @return A string containing a selector expression to match elements
	 *         against.
	 */
	public native GQuery parent(String selector)/*-{
		return this.parent(selector);
	}-*/;
	
	
	/**
	 * Get the ancestors of each element in the current set of matched elements,
	 * optionally filtered by a selector.
	 * 
	 * @return
	 */
	public native GQuery parents()/*-{
		return this.parents();
	}-*/;

	/**
	 * Get the ancestors of each element in the current set of matched elements,
	 * optionally filtered by a selector.
	 * 
	 * @param selector
	 *          A string containing a selector expression to match elements
	 *          against.
	 * 
	 * @return
	 */
	public native GQuery parents(String selector)/*-{
		return this.parents(selector);
	}-*/;
	
	
	/**
	 * Get the ancestors of each element in the current set of matched elements,
	 * up to but not including the element matched by the selector.
	 * 
	 * @param selector
	 *          A string containing a selector expression to indicate where to
	 *          stop matching ancestor elements.
	 * 
	 * @return
	 */
	public native GQuery parentsUntil(String selector)/*-{
		return this.parentsUntil(selector);
	}-*/;
	
	
	/**
	 * Get the immediately preceding sibling of each element in the set of matched
	 * elements, optionally filtered by a selector.
	 * 
	 * @param selector
	 *          A string containing a selector expression to match elements
	 *          against.
	 * 
	 * @return
	 */
	public native GQuery prev(String selector)/*-{
		return this.prev(selector);
	}-*/;

	/**
	 * Get the immediately preceding sibling of each element in the set of matched
	 * elements.
	 * 
	 * @return
	 */
	public native GQuery prev()/*-{
		return this.prev();
	}-*/;
	
	
	/**
	 * Get all preceding siblings of each element in the set of matched elements,
	 * optionally filtered by a selector.
	 * 
	 * @return
	 */
	public native GQuery prevAll()/*-{
		return this.prevAll();
	}-*/;

	/**
	 * Get all preceding siblings of each element in the set of matched elements,
	 * optionally filtered by a selector.
	 * 
	 * @param selector
	 *          A string containing a selector expression to match elements
	 *          against.
	 * 
	 * @return
	 */
	public native GQuery prevAll(String selector)/*-{
		return this.prevAll(selector);
	}-*/;
	
	
	/**
	 * Get all preceding siblings of each element up to but not including the
	 * element matched by the selector.
	 * 
	 * @param selector
	 *          A string containing a selector expression to indicate where to
	 *          stop matching preceding sibling elements.
	 * 
	 * @return
	 */
	public native GQuery prevUntil(String selector)/*-{
		return this.prevUntil(selector);
	}-*/;

	
	/**
	 * Get the siblings of each element in the set of matched elements, optionally
	 * filtered by a selector.
	 * 
	 * @param selector
	 *          A string containing a selector expression to match elements
	 *          against.
	 * 
	 * @return
	 */
	public native GQuery siblings(String selector)/*-{
		return this.siblings(selector);
	}-*/;

	/**
	 * Get the siblings of each element in the set of matched elements, optionally
	 * filtered by a selector.
	 * 
	 * @return
	 */
	public native GQuery siblings()/*-{
		return this.siblings();
	}-*/;
	
	/**
	 * Reduce the set of matched elements to a subset specified by a range of
	 * indices.
	 * 
	 * @param start
	 *          An integer indicating the 0-based position after which the
	 *          elements are selected. If negative, it indicates an offset from
	 *          the end of the set.
	 * 
	 * @param end
	 *          An integer indicating the 0-based position before which the
	 *          elements stop being selected. If negative, it indicates an offset
	 *          from the end of the set. If omitted, the range continues until the
	 *          end of the set.
	 * 
	 * @return
	 */
	public native GQuery slice(int start, int end)/*-{
		return this.slice(start,end);
	}-*/;

	/**
	 * Reduce the set of matched elements to a subset specified by a range of
	 * indices.
	 * 
	 * @param start
	 *          An integer indicating the 0-based position after which the
	 *          elements are selected. If negative, it indicates an offset from
	 *          the end of the set.
	 * @return
	 */
	public native GQuery slice(int start)/*-{
		return this.slice(start);
	}-*/;
	
	//Traversing API End
	
	//Manipulation API Start
	/**
	 * Insert content, specified by the parameter, after each element in the set
	 * of matched elements
	 * 
	 * @param element
	 *          An element, HTML string, or jQuery object to insert after each
	 *          element in the set of matched elements.
	 * 
	 * @return
	 */
	public native GQuery after(Node element)/*-{
		return this.after(element);
	}-*/;

	/**
	 * Insert content, specified by the parameter, after each element in the set
	 * of matched elements
	 * 
	 * @param element
	 *          An element, HTML string, or jQuery object to insert after each
	 *          element in the set of matched elements.
	 * 
	 * @return
	 */
	public native GQuery after(GQuery element)/*-{
		return this.after(element);
	}-*/;

	/**
	 * Insert content, specified by the parameter, after each element in the set
	 * of matched elements
	 * 
	 * @param element
	 *          An element, HTML string, or jQuery object to insert after each
	 *          element in the set of matched elements.
	 * 
	 * @return
	 */
	public native GQuery after(String element)/*-{
		return this.after(element);
	}-*/;
	
	/**
	 * Insert content, specified by the parameter, after each element in the set
	 * of matched elements.
	 * 
	 * @param func
	 *          function(index)A function that returns an HTML string to insert
	 *          after each element in the set of matched elements.
	 * 
	 * 
	 * @return
	 */
	public native GQuery after(Func func)/*-{
		return this.after(function(index){
			func.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;I)("index",index);
			func.@com.mustang.core.client.type.Func::apply(Lcom/mustang/core/client/GQuery;)(this);
			return func.@com.mustang.core.client.type.Func::returnString()();
		});
	}-*/;
	
	/**
	 * Insert content, specified by the parameter, to the end of each element in
	 * the set of matched elements.
	 * 
	 * @param element
	 *          An element, HTML string, or jQuery object to insert at the end of
	 *          each element in the set of matched elements.
	 * 
	 * @return
	 */
	public native GQuery append(Node element)/*-{
		return this.append(element);
	}-*/;

	/**
	 * Insert content, specified by the parameter, to the end of each element in
	 * the set of matched elements.
	 * 
	 * @param element
	 *          An element, HTML string, or jQuery object to insert at the end of
	 *          each element in the set of matched elements.
	 * 
	 * @return
	 */
	public native GQuery append(String element)/*-{
		return this.append(element);
	}-*/;

	/**
	 * Insert content, specified by the parameter, to the end of each element in
	 * the set of matched elements.
	 * 
	 * @param element
	 *          An element, HTML string, or jQuery object to insert at the end of
	 *          each element in the set of matched elements.
	 * 
	 * @return
	 */
	public native GQuery append(GQuery element)/*-{
		return this.append(element);
	}-*/;
	
	
	/**
	 * Insert content, specified by the parameter, to the end of each element in
	 * the set of matched elements.
	 * 
	 * @param func
	 *          function(index, html)A function that returns an HTML string to
	 *          insert at the end of each element in the set of matched elements.
	 *          Receives the index position of the element in the set and the old
	 *          HTML value of the element as arguments.
	 * 
	 * 
	 * 
	 * @return
	 */
	public native GQuery append(Func func)/*-{
		return this.append(function(index,html){
			func.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;I)("index",index);
			func.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;Ljava/lang/String;)("html",html);
			func.@com.mustang.core.client.type.Func::apply(Lcom/mustang/core/client/GQuery;)(this);
			return func.@com.mustang.core.client.type.Func::returnString()();
		});
	}-*/;

	//Manipulation API End
	
	public native String toStr()/*-{
		return this.innerHTML;
	}-*/;

	
	public native void mouseover(Func func)/*-{
		this.mouseover(function(){
			func.@com.mustang.core.client.type.Func::apply(Lcom/mustang/core/client/GQuery;)(this);
		});
	}-*/;	
	
	public native boolean isXMLDoc(Element doc)/*-{
		return $wnd.jQuery.isXMLDoc(document);
	}-*/;

	public native void click(Func func)/*-{
		this.click(function(event){
			func.@com.mustang.core.client.type.Func::setArgument(Ljava/lang/String;Lcom/mustang/core/client/type/JsObject;)("event",event);
			func.@com.mustang.core.client.type.Func::apply(Lcom/mustang/core/client/GQuery;)(this);
		});
	}-*/;

	public native void ready(Func func)/*-{
		this.ready(function(){
			func.@com.mustang.core.client.type.Func::apply(Lcom/mustang/core/client/GQuery;)(this);
		});
	}-*/;

	public native void show(String style)/*-{
		this.show(style);
	}-*/;

	public native void animate(JsObject props, String duration, Func func)/*-{
		if(func===null||typeof func=='undefined'){
			this.animate(props,duration);
		}else{
			this.animate(props,duration,function(){
				func.@com.mustang.core.client.type.Func::apply(Lcom/mustang/core/client/GQuery;)(this);
			});
		}
	}-*/;

	public void animate(JsObject props, String duration)
	{
		this.animate(props, duration, null);
	}

	public native void hide()/*-{
		this.hide();
	}-*/;

	public native void appendTo(String node)/*-{
		this.appendTo(node);
	}-*/;
	
	
	
	
	public native void text(String text)/*-{
		this.text(text);
	}-*/;
	
	public native String text()/*-{
		return this.text();
	}-*/;
	


	public native void one(String property, Func func)/*-{
		this.one(property,function(){
			func.@com.mustang.core.client.type.Func::apply(Lcom/mustang/core/client/GQuery;)(this);
		})
	}-*/;
	
	public native int length()/*-{
		return this.length;
	}-*/;
	
	public native String get()/*-{
	return this.length();
}-*/;
	
	
	/**
	 * Return the Element role of this GQuery object,it is useful when you try to 
	 * access the element attributes such as "tagName","innerHTML" ,"title" etc.
	 * 
	 * @return cast this gQuery instance to element object
	 */
	public Element toElement(){
		return Element.as(this);
	}
	
}
